import os.path
import time

from util import plot

class LoggingError(Exception):
    pass

class Channel(object):
    
    def __init__(self,name,path,maxData=1000):
        self.name = name
        self.data = [ ]
        self.path = path
        self.index = 0
        self.maxData = maxData
    
    def flush(self):
        """
        Flushes records from memory to disk
        """
        output = open(os.path.join(self.path,'%s_%d.log' % (self.name,self.index)),"w")
        for (timestamp,values) in self.data:
            output.write(str(timestamp))
            for value in values:
                output.write(' ' + str(value))
            output.write('\n')
        output.close()
        self.index += 1
    
    def record(self,values):
        """
        Timestamps and records a tuple of values
        """
        now = time.time()
        try:
            values = map(float,values)
        except ValueError:
            raise LoggingError('Unable to convert %s values %r' % (self.name,values))
        self.data.append((now,values))
        if len(self.data) >= self.maxData:
            self.flush()
    
    def last(self):
        """
        Returns the most recent values recorded
        """
        return self.data[-1] if self.data else None
        
    def series(self,index=0):
        """
        Returns a data series suitable for plotting
        """
        return ChannelSeries(self.data,index)


class ChannelSeries(object):

    def __init__(self,data,index):
        self.data = data
        self.index = index

    def __iter__(self):
        return ((plot.convertTimestamp(timestamp),values[self.index])
            for (timestamp,values) in self.data)


class Logger(object):
    
    def __init__(self,path):
        self.path = os.path.join(path,'data')
        self.channels = { }
    
    def record(self,channelName,channelValues):
        if not channelName in self.channels:
            print 'Creating new channel for "%s"' % channelName
            self.channels[channelName] = Channel(channelName,self.path)
        self.channels[channelName].record(channelValues)

    def get(self,channelName):
        if channelName in self.channels:
            return self.channels[channelName]

    def dump(self):
        for name in self.channels:
            print 'Channel %s has recorded %d values' % (name,len(self.channels[name].data))